{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Introspection\n",
    "=============\n",
    "\n",
    "A Python code can ask and answer questions about itself and the objects it is manipulating.\n",
    "\n",
    "dir()\n",
    "-----\n",
    "\n",
    "<span>`dir()`</span> is a built-in function which returns a list of all the names belonging to some namespace.\n",
    "\n",
    "-   If no arguments are passed to dir (i.e. <span>`dir()`</span>), it inspects the namespace in which it was called.\n",
    "\n",
    "-   If <span>`dir`</span> is given an argument (i.e. <span>`dir(<object>)`</span>, then it inspects the namespace of the object which it was passed.\n",
    "\n",
    "For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__add__',\n",
       " '__class__',\n",
       " '__contains__',\n",
       " '__delattr__',\n",
       " '__delitem__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__getitem__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__iadd__',\n",
       " '__imul__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__iter__',\n",
       " '__le__',\n",
       " '__len__',\n",
       " '__lt__',\n",
       " '__mul__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__reversed__',\n",
       " '__rmul__',\n",
       " '__setattr__',\n",
       " '__setitem__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " 'append',\n",
       " 'clear',\n",
       " 'copy',\n",
       " 'count',\n",
       " 'extend',\n",
       " 'index',\n",
       " 'insert',\n",
       " 'pop',\n",
       " 'remove',\n",
       " 'reverse',\n",
       " 'sort']"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# NBVAL_IGNORE_OUTPUT\n",
    "apples = ['Cox', 'Braeburn', 'Jazz']\n",
    "dir(apples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['In',\n",
       " 'Out',\n",
       " '_',\n",
       " '__',\n",
       " '___',\n",
       " '__builtin__',\n",
       " '__builtins__',\n",
       " '__doc__',\n",
       " '__loader__',\n",
       " '__name__',\n",
       " '__package__',\n",
       " '__spec__',\n",
       " '_dh',\n",
       " '_i',\n",
       " '_i1',\n",
       " '_ih',\n",
       " '_ii',\n",
       " '_iii',\n",
       " '_oh',\n",
       " '_sh',\n",
       " 'exit',\n",
       " 'get_ipython',\n",
       " 'quit']"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# NBVAL_IGNORE_OUTPUT\n",
    "dir()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__add__',\n",
       " '__class__',\n",
       " '__contains__',\n",
       " '__delattr__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__getitem__',\n",
       " '__getnewargs__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__iter__',\n",
       " '__le__',\n",
       " '__len__',\n",
       " '__lt__',\n",
       " '__mod__',\n",
       " '__mul__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__rmod__',\n",
       " '__rmul__',\n",
       " '__setattr__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " 'capitalize',\n",
       " 'casefold',\n",
       " 'center',\n",
       " 'count',\n",
       " 'encode',\n",
       " 'endswith',\n",
       " 'expandtabs',\n",
       " 'find',\n",
       " 'format',\n",
       " 'format_map',\n",
       " 'index',\n",
       " 'isalnum',\n",
       " 'isalpha',\n",
       " 'isdecimal',\n",
       " 'isdigit',\n",
       " 'isidentifier',\n",
       " 'islower',\n",
       " 'isnumeric',\n",
       " 'isprintable',\n",
       " 'isspace',\n",
       " 'istitle',\n",
       " 'isupper',\n",
       " 'join',\n",
       " 'ljust',\n",
       " 'lower',\n",
       " 'lstrip',\n",
       " 'maketrans',\n",
       " 'partition',\n",
       " 'replace',\n",
       " 'rfind',\n",
       " 'rindex',\n",
       " 'rjust',\n",
       " 'rpartition',\n",
       " 'rsplit',\n",
       " 'rstrip',\n",
       " 'split',\n",
       " 'splitlines',\n",
       " 'startswith',\n",
       " 'strip',\n",
       " 'swapcase',\n",
       " 'title',\n",
       " 'translate',\n",
       " 'upper',\n",
       " 'zfill']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# NBVAL_IGNORE_OUTPUT\n",
    "name = \"Peter\"\n",
    "dir(name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Magic names\n",
    "\n",
    "You will find many names which both start and end with a double underscore (e.g. <span>`__name__`</span>). These are called magic names. Functions with magic names provide the implementation of particular python functionality.\n",
    "\n",
    "For example, the application of the <span>`str`</span> to an object <span>`a`</span>, i.e. <span>`str(a)`</span>, will – internally – result in the method <span>`a.__str__()`</span> being called. This method <span>`__str__`</span> generally needs to return a string. The idea is that the <span>`__str__()`</span> method should be defined for all objects (including those that derive from new classes that a programmer may create) so that all objects (independent of their type or class) can be printed using the <span>`str()`</span> function. The actual conversion of some object <span>`x`</span> to the string is then done via the object specific method <span>`x.__str__()`</span>.\n",
    "\n",
    "We can demonstrate this by creating a class <span>`my_int`</span> which inherits from the Python’s integer base class, and overrides the <span>`__str__`</span> method. (It requires more Python knowledge than provided up to this point in the text to be able to understand this example.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a * b =  12\n",
      "Type a =  <class '__main__.my_int'> str(a) =  my_int: 3\n",
      "Type b =  <class 'int'> str(b) =  4\n"
     ]
    }
   ],
   "source": [
    "class my_int(int): \n",
    "    \"\"\"Inherited from int\"\"\" \n",
    "    def __str__(self): \n",
    "        \"\"\"Tailored str representation of my int\"\"\" \n",
    "        return \"my_int: %s\" % (int.__str__(self))\n",
    " \n",
    "a = my_int(3)\n",
    "b = int(4)            # equivalent to b = 4\n",
    "print(\"a * b = \", a * b)\n",
    "print(\"Type a = \", type(a), \"str(a) = \", str(a))\n",
    "print(\"Type b = \", type(b), \"str(b) = \", str(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Further Reading\n",
    "\n",
    "See →[Python documentation, Data Model](http://docs.python.org/reference/datamodel.html)\n",
    "\n",
    "type\n",
    "----\n",
    "\n",
    "The <span>`type(<object>)`</span> command returns the type of an object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "float"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(1.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "str"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(\"Python\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "module"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math\n",
    "type(math)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "builtin_function_or_method"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(math.sin)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "isinstance\n",
    "----------\n",
    "\n",
    "<span>`isinstance(<object>, <typespec>)`</span> returns True if the given object is an instance of the given type, or any of its superclasses. Use <span>`help(isinstance`</span>) for the full syntax."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(2,int)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(2.,int)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(a,int)    # a is an instance of my_int"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "__main__.my_int"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "help\n",
    "----\n",
    "\n",
    "-   The <span>`help(<object>)`</span> function will report the docstring (magic attritube with name <span>`__doc__`</span>) of the object that it is given, sometimes complemented with additional information. In the case of functions, <span>`help`</span> will also show the list of arguments that the function accepts (but it cannot provide the return value).\n",
    "\n",
    "-   <span>`help()`</span> starts an interactive help environment.\n",
    "\n",
    "-   It is common to use the <span>`help`</span> command a lot to remind oneself of the syntax and semantic of commands.\n",
    "\n",
    "<!-- -->"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function isinstance in module builtins:\n",
      "\n",
      "isinstance(obj, class_or_tuple, /)\n",
      "    Return whether an object is an instance of a class or of a subclass thereof.\n",
      "    \n",
      "    A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to\n",
      "    check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)\n",
      "    or ...`` etc.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(isinstance)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function sin in module math:\n",
      "\n",
      "sin(...)\n",
      "    sin(x)\n",
      "    \n",
      "    Return the sine of x (measured in radians).\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "help(math.sin)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on module math:\n",
      "\n",
      "NAME\n",
      "    math\n",
      "\n",
      "MODULE REFERENCE\n",
      "    https://docs.python.org/3.6/library/math\n",
      "    \n",
      "    The following documentation is automatically generated from the Python\n",
      "    source files.  It may be incomplete, incorrect or include features that\n",
      "    are considered implementation detail and may vary between Python\n",
      "    implementations.  When in doubt, consult the module reference at the\n",
      "    location listed above.\n",
      "\n",
      "DESCRIPTION\n",
      "    This module is always available.  It provides access to the\n",
      "    mathematical functions defined by the C standard.\n",
      "\n",
      "FUNCTIONS\n",
      "    acos(...)\n",
      "        acos(x)\n",
      "        \n",
      "        Return the arc cosine (measured in radians) of x.\n",
      "    \n",
      "    acosh(...)\n",
      "        acosh(x)\n",
      "        \n",
      "        Return the inverse hyperbolic cosine of x.\n",
      "    \n",
      "    asin(...)\n",
      "        asin(x)\n",
      "        \n",
      "        Return the arc sine (measured in radians) of x.\n",
      "    \n",
      "    asinh(...)\n",
      "        asinh(x)\n",
      "        \n",
      "        Return the inverse hyperbolic sine of x.\n",
      "    \n",
      "    atan(...)\n",
      "        atan(x)\n",
      "        \n",
      "        Return the arc tangent (measured in radians) of x.\n",
      "    \n",
      "    atan2(...)\n",
      "        atan2(y, x)\n",
      "        \n",
      "        Return the arc tangent (measured in radians) of y/x.\n",
      "        Unlike atan(y/x), the signs of both x and y are considered.\n",
      "    \n",
      "    atanh(...)\n",
      "        atanh(x)\n",
      "        \n",
      "        Return the inverse hyperbolic tangent of x.\n",
      "    \n",
      "    ceil(...)\n",
      "        ceil(x)\n",
      "        \n",
      "        Return the ceiling of x as an Integral.\n",
      "        This is the smallest integer >= x.\n",
      "    \n",
      "    copysign(...)\n",
      "        copysign(x, y)\n",
      "        \n",
      "        Return a float with the magnitude (absolute value) of x but the sign \n",
      "        of y. On platforms that support signed zeros, copysign(1.0, -0.0) \n",
      "        returns -1.0.\n",
      "    \n",
      "    cos(...)\n",
      "        cos(x)\n",
      "        \n",
      "        Return the cosine of x (measured in radians).\n",
      "    \n",
      "    cosh(...)\n",
      "        cosh(x)\n",
      "        \n",
      "        Return the hyperbolic cosine of x.\n",
      "    \n",
      "    degrees(...)\n",
      "        degrees(x)\n",
      "        \n",
      "        Convert angle x from radians to degrees.\n",
      "    \n",
      "    erf(...)\n",
      "        erf(x)\n",
      "        \n",
      "        Error function at x.\n",
      "    \n",
      "    erfc(...)\n",
      "        erfc(x)\n",
      "        \n",
      "        Complementary error function at x.\n",
      "    \n",
      "    exp(...)\n",
      "        exp(x)\n",
      "        \n",
      "        Return e raised to the power of x.\n",
      "    \n",
      "    expm1(...)\n",
      "        expm1(x)\n",
      "        \n",
      "        Return exp(x)-1.\n",
      "        This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x.\n",
      "    \n",
      "    fabs(...)\n",
      "        fabs(x)\n",
      "        \n",
      "        Return the absolute value of the float x.\n",
      "    \n",
      "    factorial(...)\n",
      "        factorial(x) -> Integral\n",
      "        \n",
      "        Find x!. Raise a ValueError if x is negative or non-integral.\n",
      "    \n",
      "    floor(...)\n",
      "        floor(x)\n",
      "        \n",
      "        Return the floor of x as an Integral.\n",
      "        This is the largest integer <= x.\n",
      "    \n",
      "    fmod(...)\n",
      "        fmod(x, y)\n",
      "        \n",
      "        Return fmod(x, y), according to platform C.  x % y may differ.\n",
      "    \n",
      "    frexp(...)\n",
      "        frexp(x)\n",
      "        \n",
      "        Return the mantissa and exponent of x, as pair (m, e).\n",
      "        m is a float and e is an int, such that x = m * 2.**e.\n",
      "        If x is 0, m and e are both 0.  Else 0.5 <= abs(m) < 1.0.\n",
      "    \n",
      "    fsum(...)\n",
      "        fsum(iterable)\n",
      "        \n",
      "        Return an accurate floating point sum of values in the iterable.\n",
      "        Assumes IEEE-754 floating point arithmetic.\n",
      "    \n",
      "    gamma(...)\n",
      "        gamma(x)\n",
      "        \n",
      "        Gamma function at x.\n",
      "    \n",
      "    gcd(...)\n",
      "        gcd(x, y) -> int\n",
      "        greatest common divisor of x and y\n",
      "    \n",
      "    hypot(...)\n",
      "        hypot(x, y)\n",
      "        \n",
      "        Return the Euclidean distance, sqrt(x*x + y*y).\n",
      "    \n",
      "    isclose(...)\n",
      "        isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) -> bool\n",
      "        \n",
      "        Determine whether two floating point numbers are close in value.\n",
      "        \n",
      "           rel_tol\n",
      "               maximum difference for being considered \"close\", relative to the\n",
      "               magnitude of the input values\n",
      "            abs_tol\n",
      "               maximum difference for being considered \"close\", regardless of the\n",
      "               magnitude of the input values\n",
      "        \n",
      "        Return True if a is close in value to b, and False otherwise.\n",
      "        \n",
      "        For the values to be considered close, the difference between them\n",
      "        must be smaller than at least one of the tolerances.\n",
      "        \n",
      "        -inf, inf and NaN behave similarly to the IEEE 754 Standard.  That\n",
      "        is, NaN is not close to anything, even itself.  inf and -inf are\n",
      "        only close to themselves.\n",
      "    \n",
      "    isfinite(...)\n",
      "        isfinite(x) -> bool\n",
      "        \n",
      "        Return True if x is neither an infinity nor a NaN, and False otherwise.\n",
      "    \n",
      "    isinf(...)\n",
      "        isinf(x) -> bool\n",
      "        \n",
      "        Return True if x is a positive or negative infinity, and False otherwise.\n",
      "    \n",
      "    isnan(...)\n",
      "        isnan(x) -> bool\n",
      "        \n",
      "        Return True if x is a NaN (not a number), and False otherwise.\n",
      "    \n",
      "    ldexp(...)\n",
      "        ldexp(x, i)\n",
      "        \n",
      "        Return x * (2**i).\n",
      "    \n",
      "    lgamma(...)\n",
      "        lgamma(x)\n",
      "        \n",
      "        Natural logarithm of absolute value of Gamma function at x.\n",
      "    \n",
      "    log(...)\n",
      "        log(x[, base])\n",
      "        \n",
      "        Return the logarithm of x to the given base.\n",
      "        If the base not specified, returns the natural logarithm (base e) of x.\n",
      "    \n",
      "    log10(...)\n",
      "        log10(x)\n",
      "        \n",
      "        Return the base 10 logarithm of x.\n",
      "    \n",
      "    log1p(...)\n",
      "        log1p(x)\n",
      "        \n",
      "        Return the natural logarithm of 1+x (base e).\n",
      "        The result is computed in a way which is accurate for x near zero.\n",
      "    \n",
      "    log2(...)\n",
      "        log2(x)\n",
      "        \n",
      "        Return the base 2 logarithm of x.\n",
      "    \n",
      "    modf(...)\n",
      "        modf(x)\n",
      "        \n",
      "        Return the fractional and integer parts of x.  Both results carry the sign\n",
      "        of x and are floats.\n",
      "    \n",
      "    pow(...)\n",
      "        pow(x, y)\n",
      "        \n",
      "        Return x**y (x to the power of y).\n",
      "    \n",
      "    radians(...)\n",
      "        radians(x)\n",
      "        \n",
      "        Convert angle x from degrees to radians.\n",
      "    \n",
      "    sin(...)\n",
      "        sin(x)\n",
      "        \n",
      "        Return the sine of x (measured in radians).\n",
      "    \n",
      "    sinh(...)\n",
      "        sinh(x)\n",
      "        \n",
      "        Return the hyperbolic sine of x.\n",
      "    \n",
      "    sqrt(...)\n",
      "        sqrt(x)\n",
      "        \n",
      "        Return the square root of x.\n",
      "    \n",
      "    tan(...)\n",
      "        tan(x)\n",
      "        \n",
      "        Return the tangent of x (measured in radians).\n",
      "    \n",
      "    tanh(...)\n",
      "        tanh(x)\n",
      "        \n",
      "        Return the hyperbolic tangent of x.\n",
      "    \n",
      "    trunc(...)\n",
      "        trunc(x:Real) -> Integral\n",
      "        \n",
      "        Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic method.\n",
      "\n",
      "DATA\n",
      "    e = 2.718281828459045\n",
      "    inf = inf\n",
      "    nan = nan\n",
      "    pi = 3.141592653589793\n",
      "    tau = 6.283185307179586\n",
      "\n",
      "FILE\n",
      "    /Users/fangohr/anaconda3/lib/python3.6/lib-dynload/math.cpython-36m-darwin.so\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# NBVAL_IGNORE_OUTPUT\n",
    "help(math)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The <span>`help`</span> function needs to be given the name of an object (which must exist in the current name space). For example py<span>help(math.sqrt)</span> will not work if the <span>`math`</span> module has not been imported before"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function sqrt in module math:\n",
      "\n",
      "sqrt(...)\n",
      "    sqrt(x)\n",
      "    \n",
      "    Return the square root of x.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# NBVAL_IGNORE_OUTPUT\n",
    "help(math.sqrt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function sqrt in module math:\n",
      "\n",
      "sqrt(...)\n",
      "    sqrt(x)\n",
      "    \n",
      "    Return the square root of x.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# NBVAL_IGNORE_OUTPUT\n",
    "import math\n",
    "help(math.sqrt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Instead of importing the module, we could also have given the *string* of <span>`math.sqrt`</span> to the help function, i.e.:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function sqrt in math:\n",
      "\n",
      "math.sqrt = sqrt(...)\n",
      "    sqrt(x)\n",
      "    \n",
      "    Return the square root of x.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# NBVAL_IGNORE_OUTPUT\n",
    "help('math.sqrt')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<span>`help`</span> is a function which gives information about the object which is passed as its argument. Most things in Python (classes, functions, modules, etc.) are objects, and therefor can be passed to help. There are, however, some things on which you might like to ask for help, which are not existing Python objects. In such cases it is often possible to pass a string containing the name of the thing or concept to help, for example\n",
    "\n",
    "-   <span>`help(’modules’)`</span> will generate a list of all modules which can be imported into the current interpreter. Note that help(modules) (note absence of quotes) will result in a NameError (unless you are unlucky enough to have a variable called modules floating around, in which case you will get help on whatever that variable happens to refer to.)\n",
    "\n",
    "-   <span>`help(’some_module’)`</span>, where some\\_module is a module which has not been imported yet (and therefor isn’t an object yet), will give you that module’s help information.\n",
    "\n",
    "-   <span>`help(’some_keyword’)`</span>: For example <span>`and`</span>, <span>`if`</span> or <span>`print`</span> (*i.e.* <span>`help(’and’)`</span>, <span>`help(’if’)`</span> and <span>`help(’print’)`</span>). These are special words recognized by Python: they are not objects and thus cannot be passed as arguments to help. Passing the name of the keyword as a string to help works, but only if you have Python’s HTML documentation installed, and the interpreter has been made aware of its location by setting the environment variable PYTHONDOCS.\n",
    "\n",
    "Docstrings\n",
    "----------\n",
    "\n",
    "The command <span>`help(<object>)`</span> accesses the documentation strings of objects.\n",
    "\n",
    "Any literal string apparing as the first item in the definition of a class, function, method or module, is taken to be its *docstring*.\n",
    "\n",
    "<span>`help`</span> includes the docstring in the information it displays about the object.\n",
    "\n",
    "In addition to the docstring it may display some other information, for example, in the case of functions, it displays the function’s signature.\n",
    "\n",
    "The docstring is stored in the object’s <span>`__doc__`</span> attribute."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function sin in module math:\n",
      "\n",
      "sin(...)\n",
      "    sin(x)\n",
      "    \n",
      "    Return the sine of x (measured in radians).\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# NBVAL_IGNORE_OUTPUT\n",
    "help(math.sin)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sin(x)\n",
      "\n",
      "Return the sine of x (measured in radians).\n"
     ]
    }
   ],
   "source": [
    "# NBVAL_IGNORE_OUTPUT\n",
    "print(math.sin.__doc__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For user-defined functions, classes, types, modules, …), one should always provide a docstring.\n",
    "\n",
    "Documenting a user-provided function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 8)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def power2and3(x):\n",
    "    \"\"\"Returns the tuple (x**2, x**3)\"\"\"\n",
    "    return x**2 ,x**3\n",
    "\n",
    "power2and3(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(20.25, 91.125)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "power2and3(4.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((-1+0j), (-0-1j))"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "power2and3(0+1j)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function power2and3 in module __main__:\n",
      "\n",
      "power2and3(x)\n",
      "    Returns the tuple (x**2, x**3)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(power2and3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Returns the tuple (x**2, x**3)\n"
     ]
    }
   ],
   "source": [
    "print(power2and3.__doc__)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
